package com.example.netdemo.base

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.example.netdemo.retrofit.Resource
import com.example.netdemo.retrofit.RetrofitManager
import com.google.gson.JsonIOException
import com.google.gson.JsonParseException
import com.google.gson.JsonSyntaxException
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

open class BaseRepository {
    protected fun <T> create(service: Class<T>): T {
        return RetrofitManager.get().create(service)
    }

    protected fun <T : Any> Observable<BaseResponse<T>>.commonHandle(): Pair<LiveData<Resource<T>>, Disposable> {
        val liveData = MutableLiveData<Resource<T>>()
        liveData.postValue(Resource.loading())
        val disposable = this.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                {
                    when (it.code) {
                        Constant.SUCCESS_CODE -> liveData.postValue(Resource.success(it.data))
                        else -> liveData.postValue(Resource.error(it.msg))
                    }
                },
                {
                    liveData.postValue(getError(it))
                }
            )
        return Pair(liveData, disposable)
    }

    private fun getError(throwable: Throwable): Resource.Error {
        return when (throwable) {
            is SocketTimeoutException -> {
                Resource.error("连接超时，请稍后再试", throwable)
            }

            is ConnectException -> {
                Resource.error("连接异常", throwable)
            }

            is UnknownHostException -> {
                Resource.error("找不到主机", throwable)
            }

            is JsonSyntaxException -> {
                parseError("JSON数据语法错误", throwable)
            }

            is JSONException -> {
                parseError("JSON数据解析异常", throwable)
            }

            is JsonIOException -> {
                parseError("JSON IO异常", throwable)
            }

            is JsonParseException -> {
                parseError("JSON数据解析异常", throwable)
            }

            is HttpException -> {when (throwable.code()) {
                401 -> Resource.error("请重新登录", throwable)
                404 -> Resource.error("接口不存在", throwable)
                500 -> Resource.error("服务器内部错误", throwable)
                else -> Resource.error("网络错误", throwable)
            }
                Resource.error("网络错误", throwable)
            }

            else -> {
                Resource.error("未知错误", throwable)
            }
        }
    }

    private fun parseError(message: String = "数据解析异常", throwable: Throwable) =
        Resource.error(message, throwable)
}